package com.ytd.smartcanteen.weighting.util;

import com.ytd.smartcanteen.weighting.bean.MealInfo;
import com.ytd.smartcanteen.weighting.bean.response.GetConsumeResponse;
import com.ytd.smartcanteen.weighting.constants.Constants;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Locale;

/**
 * Your class notes
 *
 * @author gaoguanchao
 * @since 2023/6/1 0001
 */
public class MealInfoUtil {
    private static final String FORMAT_TEXT = "%.2f";
    private static final String FORMAT_TEXT_100 = "%.0f";

    private static MealInfo sMealInfo;

    private static BigDecimal sWeightValue;
    private static BigDecimal sFloatValue;
    private static BigDecimal sPriceValue;

    public static String getPriceFormat(Double price) {
        return String.format(Locale.CHINA, FORMAT_TEXT, price);
    }

    public static String getValueFormat(Double price) {
        if (price > 100) {
            return String.format(Locale.CHINA, FORMAT_TEXT_100, price);
        }
        return String.format(Locale.CHINA, FORMAT_TEXT, price);
    }

    public static void initMealInfo(MealInfo mealInfo) {
        sMealInfo = mealInfo;
        if (sMealInfo == null) {
            return;
        }
        switch (sMealInfo.calcType) {
            case Constants.CALC_TYPE_WEIGHT:
                sWeightValue = new BigDecimal(sMealInfo.weight);
                break;
            case Constants.CALC_TYPE_PORTION:
                sWeightValue = new BigDecimal(sMealInfo.onePortionWeight);
                sFloatValue = new BigDecimal(sMealInfo.floatingWeight);
                break;
            default:
                sWeightValue = BigDecimal.ONE;
        }
        sPriceValue = new BigDecimal(sMealInfo.price);
    }

    public static BigDecimal getChangePrice(GetConsumeResponse consumeResponse, BigDecimal value) {
        BigDecimal result = BigDecimal.ZERO;
        if (sMealInfo == null || consumeResponse == null || sPriceValue == null) {
            return result;
        }
        if (consumeResponse.fixedPriceAndTaken) {//统一价格多次打菜价格为0
            return BigDecimal.ZERO;
        }
        if (value.compareTo(BigDecimal.ZERO) < 0) {
            value = BigDecimal.ZERO;
        }
        BigDecimal startingWeight = null;
        if (consumeResponse.startingWeight > 0) {
            startingWeight = BigDecimal.valueOf(consumeResponse.startingWeight);
        }
        if (startingWeight != null && value.compareTo(startingWeight) < 0) {
            value = BigDecimal.ZERO;
        }
        if (value.compareTo(BigDecimal.ZERO) == 0) {
            return value;
        }
        if (sWeightValue == null || sWeightValue.compareTo(BigDecimal.ZERO) == 0) {
            sWeightValue = BigDecimal.ONE;//避免除零 bug
        }
        switch (sMealInfo.calcType) {
            case Constants.CALC_TYPE_WEIGHT:
                // 餐品单价（保留4位小数，四舍五入） = xx元/xx克
                BigDecimal itemPrice = sPriceValue.divide(sWeightValue, 4, RoundingMode.HALF_UP);
                // 餐品总价（保留2位小数，四舍五入） = 餐品单价 * 餐品重量
                result = itemPrice.multiply(value).setScale(2, RoundingMode.HALF_UP);
                break;
            case Constants.CALC_TYPE_PORTION:
                if (sFloatValue == null) {
                    sFloatValue = BigDecimal.ZERO;
                }
                // v1（向下取整） = 餐品重量/每份重量
                int v1 = value.divide(sWeightValue, 0, RoundingMode.DOWN).intValue();
                // v2（向下取整）= (餐品重量 模运算 每份重量)/(每份重量-浮动重量)
                int v2 = value.remainder(sWeightValue).divide(sWeightValue.subtract(sFloatValue), 0, RoundingMode.DOWN)
                        .intValue();
                int sum = v1 + v2;
                if (startingWeight != null) {
                    sum = Math.max(1, sum);
                }
                result = BigDecimal.valueOf(sum).multiply(sPriceValue);
                break;
            case Constants.CALC_TYPE_REGULAR:
                result = sPriceValue;
                break;
        }
        return result;
    }

    public static String getWeightUnit(MealInfo mealInfo) {
        if (mealInfo == null) {
            return "";
        }
        String weightUnit = "/" + mealInfo.weight + " " + mealInfo.weightUnit;
        switch (mealInfo.calcType) {
            case 1:
                if (mealInfo.floatingWeight == 0) {
                    weightUnit = "/" + mealInfo.numberUnitName;
                } else {
                    weightUnit = "/" + mealInfo.numberUnitName + "(" + mealInfo.onePortionWeight + "g±" +
                            mealInfo.floatingWeight + "g)";
                }
                break;
            case 2:
                weightUnit = " ";
                break;
            case 0:
            default:
                break;
        }
        return weightUnit;
    }

    public static void release() {
        sMealInfo = null;
        sWeightValue = null;
        sFloatValue = null;
        sPriceValue = null;
    }
}
